﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using My_TV_Manager.Model;

namespace My_TV_Manager.View.ContentPanel.Track
{
    [System.ComponentModel.DesignerCategory("")]

    public class DisabledLabel : Label
    {
        private Color enabledColor;
        private Color disabledColor;

        public Color EnabledColor
        {
            get { return enabledColor; }
            set { enabledColor = value; }
        }
        public Color DisabledColor
        {
            get { return disabledColor; }
            set { disabledColor = value; }
        }
        public new Boolean Enabled
        {
            get { return base.Enabled; }
            set
            {
                base.Enabled = value;
                this.Invalidate();
            }
        }

        public DisabledLabel()
        {
            this.DoubleBuffered = true;
            this.enabledColor = Color.Black;
            this.disabledColor = Color.Black;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            SolidBrush brush;
            if (this.Enabled) { brush = new SolidBrush(this.enabledColor); }
            else { brush = new SolidBrush(this.disabledColor); }

            SizeF stringSize = e.Graphics.MeasureString(this.Text, this.Font);
            int leftStart = Padding.Left, topStart = Padding.Top;

            if (this.TextAlign == ContentAlignment.MiddleCenter ||
                this.TextAlign == ContentAlignment.MiddleLeft ||
                this.TextAlign == ContentAlignment.MiddleRight)
            {
                topStart = (this.DisplayRectangle.Height - (int)stringSize.Height) / 2;
            }

            if (this.TextAlign == ContentAlignment.BottomCenter ||
                this.TextAlign == ContentAlignment.MiddleCenter ||
                this.TextAlign == ContentAlignment.TopCenter)
            {
                leftStart = (this.DisplayRectangle.Width - (int)stringSize.Width) / 2;
            }

            e.Graphics.DrawString(this.Text, this.Font, brush, leftStart, topStart);

            brush.Dispose();
            brush = null;
        }
    }

    public abstract class SeriesDisplayPanel : Panel, IComparable
    {
        #region Private Data

        protected Controller controller;

        // Data
        protected SearchResult searchResult;
        private double bannerScale;
        private int borderWidth;
        private SearchResultSortCategory sortCategory;

        // Display
        private DisabledLabel titleLabel;
        private DisabledLabel yearLabel;
        private DisabledLabel ratingLabel;
        private PictureBox bannerBox;
        protected Button manageButton;

        #endregion

        #region Properties

        public SearchResult SearchResult
        {
            get { return searchResult; }
        }
        public SearchResultSortCategory SortCategory
        {
            get { return sortCategory; }
            set
            {
                sortCategory = value;
                searchResult.SortCategory = value;
            }
        }

        #endregion

        #region Constructors

        // Base constructor
        public SeriesDisplayPanel(SearchResult searchResult, double bannerScale, Size size)
        {
            #region Format This

            // Handle the input parameters
            this.searchResult = searchResult;
            this.bannerScale = bannerScale;
            this.Size = size;

            // Handle necessary formatting for the panel
            this.borderWidth = 1;
            this.Name = "Search Result";
            this.Paint += new PaintEventHandler(SearchResultPaintHandler);
            this.Click += new EventHandler(ResultClickHandler);

            #endregion

            #region Title Display

            titleLabel = new DisabledLabel();
            titleLabel.Name = "Name";
            titleLabel.Text = searchResult.SeriesName;
            titleLabel.BackColor = Color.Transparent;
            titleLabel.Size = new Size(this.Width / 3 + 45, this.Height - 10);
            titleLabel.Location = new Point(5, (this.Height - titleLabel.Height) / 2);
            titleLabel.FlatStyle = FlatStyle.Flat;
            titleLabel.Font = new Font("Helvetica", 12.0f, FontStyle.Bold);
            titleLabel.TextAlign = ContentAlignment.MiddleLeft;
            titleLabel.Enabled = false;
            this.Controls.Add(titleLabel);

            #endregion

            #region Year Display

            yearLabel = new DisabledLabel();
            yearLabel.Name = "Year";
            yearLabel.Text = searchResult.YearStarted.ToString();
            yearLabel.BackColor = Color.Transparent;
            yearLabel.Size = new Size(this.Width / 14 + 10, this.Height - 10);
            yearLabel.Location = new Point(titleLabel.Location.X + titleLabel.Width, 
                                           (this.Height - yearLabel.Height) / 2);
            yearLabel.FlatStyle = FlatStyle.Standard;
            yearLabel.Font = new Font("Helvetica", 12.0f, FontStyle.Bold);
            yearLabel.TextAlign = ContentAlignment.MiddleCenter;
            yearLabel.Enabled = false;
            this.Controls.Add(yearLabel);

            #endregion

            #region Rating Display

            ratingLabel = new DisabledLabel();
            ratingLabel.Name = "Rating";
            ratingLabel.Text = searchResult.Rating.ToString();
            ratingLabel.BackColor = Color.Transparent;
            ratingLabel.Size = new Size(this.Width / 14 + 10, this.Height - 10);
            ratingLabel.Location = new Point(yearLabel.Location.X + yearLabel.Width, 
                                             (this.Height - ratingLabel.Height) / 2);
            ratingLabel.FlatStyle = FlatStyle.Flat;
            ratingLabel.Font = new Font("Helvetica", 12.0f, FontStyle.Bold);
            ratingLabel.TextAlign = ContentAlignment.MiddleCenter;
            ratingLabel.Enabled = false;
            this.Controls.Add(ratingLabel);

            #endregion

            #region Banner Display

            Size bannerSize = new Size((int)(searchResult.Banner.Width * bannerScale),
                                        (int)(searchResult.Banner.Height * bannerScale));
            Bitmap bannerImage = new Bitmap(searchResult.Banner, bannerSize);
            bannerBox = new PictureBox();
            bannerBox.Name = "Banner";
            bannerBox.Image = bannerImage;
            bannerBox.BackColor = Color.Transparent;
            bannerBox.Size = bannerImage.Size;
            bannerBox.Location = new Point(ratingLabel.Location.X + ratingLabel.Width + 5, 
                                           (this.Height - bannerBox.Height) / 2);
            bannerBox.EnabledChanged += new EventHandler(EnabledChangedEvent);
            bannerBox.Enabled = false;
            this.Controls.Add(bannerBox);

            #endregion

            #region Button Display

            manageButton = new Button();
            manageButton.Name = "Manage";
            manageButton.BackColor = Color.White;
            manageButton.Size = new Size(this.Width / 12, 30);
            manageButton.Location = new Point(this.Width - manageButton.Width - 10, 
                                              (this.Height - manageButton.Height) / 2);
            manageButton.FlatStyle = FlatStyle.Flat;
            manageButton.FlatAppearance.BorderSize = 0;
            manageButton.Font = new Font("Helvetica", 12.0f, FontStyle.Bold);
            manageButton.TextAlign = ContentAlignment.MiddleCenter;
            manageButton.Click += new EventHandler(ManageClickHandler);
            manageButton.MouseEnter += new EventHandler(MouseEnterHandler);
            this.Controls.Add(manageButton);

            #endregion
        }

        // Constructor using controller for program data
        public SeriesDisplayPanel(SearchResult searchResult, double bannerScale,
                                  Size size, Controller controller)
            : this(searchResult, bannerScale, size)
        {
            this.controller = controller;
        }

        #endregion

        #region Event Handlers

        // Changes the color of the panel when the mouse enters the region
        protected override void OnMouseEnter(EventArgs e)
        {
            this.BackColor = controller.SearchResultActiveColor;
            base.OnMouseEnter(e);
        }

        // Changes the color of the panel when the mouse leaves the region
        protected override void OnMouseLeave(EventArgs e)
        {
            this.BackColor = controller.SearchResultPassiveColor;
            base.OnMouseLeave(e);
        }

        private void MouseEnterHandler(object sender, EventArgs e)
        {
            this.BackColor = controller.SearchResultActiveColor;
        }

        private void EnabledChangedEvent(object sender, EventArgs e)
        {
            titleLabel.ForeColor = Color.Black;
        }

        // Handles the click on the search result, dropping down for more information
        private void ResultClickHandler(object sender, EventArgs e)
        {

        }

        // Handles the click on the manage button to add/remove a search result
        protected abstract void ManageClickHandler(object sender, EventArgs e);

        // Draws a border, since panels don't handle borders well
        private void SearchResultPaintHandler(object sender, PaintEventArgs e)
        {
            if (e.ClipRectangle.Size == this.Size)
            {
                e.Graphics.DrawRectangle(Pens.Black,
                                         e.ClipRectangle.Left,
                                         e.ClipRectangle.Top,
                                         e.ClipRectangle.Width - borderWidth,
                                         e.ClipRectangle.Height - borderWidth);
            }
        }

        #endregion

        #region IComparable Members

        public int CompareTo(object obj)
        {
            if (obj is SeriesDisplayPanel)
            {
                SeriesDisplayPanel series = (SeriesDisplayPanel)obj;

                return searchResult.CompareTo(series.SearchResult);
            }
            else
            {
                throw new ArgumentException("Object is not of type SeriesDisplayPanel");
            }
        }

        #endregion
    }
}
